from django.shortcuts import render
from django.views import View
from django import http
from django.contrib.auth import login, logout
from django_redis import  get_redis_connection
from django.contrib.auth import authenticate
from django.shortcuts import redirect
from django.conf.global_settings import SESSION_COOKIE_AGE
from django.contrib.auth.mixins import LoginRequiredMixin

import re
from users.models import User

#新用户注册
class RegisterView(View):
    '''新用户注册'''
    def get(self, request):

        return render(request, 'register.html')

    def post(self, request):
        query_dict = request.POST
        username = query_dict.get('username')
        password = query_dict.get('password')
        password2 = query_dict.get('password2')
        mobile = query_dict.get('mobile')
        sms_code = query_dict.get('sms_code')
        allow = query_dict.get('allow')

        if all([username, password, password2, mobile, sms_code, allow]) is False:
            return http.HttpResponseForbidden('缺少必传参数')
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseForbidden('请输入5-20个字符的用户名')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20位的密码')
        if password2 != password:
            return http.HttpResponseForbidden('两次密码不一致')
        if not re.match(r'^1[345789]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入11位的电话号码')

        #接收短信验证码参数
        sms_code_client = request.POST.get('sms_code')
        #保存注册数据之前，对比短信验证码是否正确
        redis_conn = get_redis_connection('verify_code')
        #用户发送的短信验证码
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        if sms_code_server is None:
            return render(request, 'register.html', {'sms_code_errmsg':'无效的短信验证码'})
        if sms_code_client != sms_code_server:
            return render(request, 'register.html', {'sms_code_errmsg': '输入短信验证码有误'})


        # User.objects.create(
        #     username = username,
        #     password = password,
        #     mobile = mobile
        # )
        #上面的写法未对密码进行加密，容易造成数据泄漏
        #User.objects会返回一个对象，create_user是django中的USER自己的方法，可以对密码进行加密
        user = User.objects.create_user(username=username, password=password, mobile=mobile)
        #状态保持（记住已登陆的用户）
        #login是django自带的功能，将登陆用户的id保存在session中，这样后续每次发送请求给服务端，就会携带用户的信息
        login(request, user)

        #return http.HttpResponse("注册成功")
        response = redirect(reversed('/'))
        # response.set_cookie('username', user.username, max_age=60 * 60 * 24 * 14)
        response.set_cookie('username', user.username, max_age=SESSION_COOKIE_AGE)

        return response


#校验用户名是否重名
class UsernameCountView(View):
    '''校验用户名是否重名'''
    def get(self, request, username):
        count = User.objects.filter(username=username).count()

        return http.JsonResponse({'count': count})

#校验手机号是否重名
class MobileCountView(View):
    '''校验手机号是否重名'''
    def get(self, request, mobile):
        count = User.objects.filter(mobile=mobile).count()

        return http.JsonResponse({'count': count})

#用户名登陆
class LoginView(View):
    '''用户名登陆'''
    def get(self, request):
        '''提供登陆页面'''
        return render(request, 'login.html')

    def post(self, request):
        '''实现登陆逻辑'''
        username = request.POST.get('username')
        password = request.POST.get('password')
        #remembered->是否记住用户
        remembered = request.POST.get('remembered') # 'on' or None
        # 3. 判断用户名及密码是否正确
        # 用户认证,通过认证返回user 反之返回None
        user = authenticate(username=username, password=password)
        if user in None:
            return render(request, 'login.html', {'account_errmsg':'用户名或密码错误'})
        #状态保持，login是django提供的一种方法
        login(request, user)
        if remembered != 'on':
            request.session.set_expiry(0) #客户没有勾选记住登陆，那么session会在会话节结束过期
        # 5. 重定向
        # return http.HttpResponse('跳转到首页')
        response = redirect(request.GET.get('next') or '/')
        # 用户登录成功存储username到cookie
        # if remembered is None:
        #     response.set_cookie('username', user.username)
        # else:
        #     response.set_cookie('username', user.username, max_age=60 * 60 * 24 * 14)

        response.set_cookie('username', user.username, max_age=SESSION_COOKIE_AGE if remembered == 'on' else None)

        return response

#退出登陆
class LogoutView(View):
    '''退出登陆'''
    def get(self, request):
        #清除session，logout是django提供的方法
        logout(request)
        #退出登陆，重定向到登陆页
        response = redirect('/login/')
        #退出登陆是清楚cookie中的username
        response.delete_cookie('username')

        return request


#用户中心
#实现方法一
# class InfoView(View):
#     def get(self, request):
#         '''提供个人信息页面'''
#         #is_authenticated是django提供的判断用户是否登陆的方法
#         if request.user.is_authenticated():
#             return render(request, 'user_center_info.html')
#         else:
#             return redirect('/login/?next=/info/')


#实现方法二
#iLoginRequiredMixin内部封装了is_authenticated,所以不需要我们像上面那样再进行判断
class InfoView(LoginRequiredMixin, View):
    def get(self, request):
        '''提供个人信息页面'''

        return redirect('user_center_info.html')
